//This file is a part of StoragePlug for Minecraft.
//http://code.google.com/p/minecraft-storageplug/
//StoragePlug is Copyright (C) 2011 Christopher Smith
//Released under the MIT license:
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights 
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//DEALINGS IN THE SOFTWARE.
//
//Related to Minecraft Copyright (C) 2009-2011 Mojang http://www.minecraft.net/

package net.minecraft.storageplug;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPStreamStorageAdapter
	implements StreamStorageProvider
{
	StreamStorageProvider next;
	
	public GZIPStreamStorageAdapter(StreamStorageProvider next)
	{
		this.next = next;
	}
	
	private static class GZIPReadOperation
		implements StreamStorageProvider.ReadOperation
	{
		final StreamStorageProvider.ReadOperation next;
		
		public GZIPReadOperation(StreamStorageProvider.ReadOperation next)
			throws Exception
		{
			this.next = next;
		}

        @Override
        public void read(InputStream stream)
            throws Exception
        {
            if(stream != null)
                next.read(new GZIPInputStream(stream));
        }

        @Override
        public Key key()
        {
            return next.key();
        }
	}
	
	public static class GZIPWriteOperation
		implements StreamStorageProvider.WriteOperation
	{
		final StreamStorageProvider.WriteOperation next;
		
		public GZIPWriteOperation(StreamStorageProvider.WriteOperation next)
			throws Exception
		{
			this.next = next;
		}

        @Override
        public void write(OutputStream stream)
            throws Exception
        {
            if(stream != null)
                next.write(new GZIPOutputStream(stream));
        }

        @Override
        public Key key()
        {
            return next.key();
        }
    }
    
    @Override
    public void readDataStream(ReadOperation op)
        throws Exception
    {
        next.readDataStream(new GZIPReadOperation(op));
    }
    
    @Override
    public void writeDataStream(WriteOperation op)
        throws Exception
    {
        next.writeDataStream(new GZIPWriteOperation(op));
    }

    @Override
    public void readDataStreamBatch(Collection<? extends ReadOperation> list)
        throws Exception
    {
        ArrayList<ReadOperation> gzipList = new ArrayList<ReadOperation>(list.size());
        
        for(ReadOperation op : list)
            gzipList.add(new GZIPReadOperation(op));
        
        next.readDataStreamBatch(gzipList);
    }

    @Override
    public void writeDataStreamBatch(Collection<? extends WriteOperation> list)
        throws Exception
    {
        ArrayList<WriteOperation> gzipList = new ArrayList<WriteOperation>(list.size());
        
        for(WriteOperation op : list)
            gzipList.add(new GZIPWriteOperation(op));
        
        next.writeDataStreamBatch(gzipList);
    }
	@Override
	public void flush()
		throws Exception
	{
		next.flush();
	}
	@Override
	public void dispose()
		throws Exception
	{
		next.dispose();		
	}
	@Override
	public Collection<? extends Key> iterKeys(Class keytype)
		throws Exception
	{
		return next.iterKeys(keytype);
	}
	@Override
	public Collection<? extends Map.Entry<String, Integer>> readUniqueIDs()
		throws Exception
	{
		return next.readUniqueIDs();
	}
	@Override
	public void writeUniqueIDs(Collection<? extends Map.Entry<String, Integer>> map)
		throws Exception
	{
		next.writeUniqueIDs(map);
	}
	@Override
	public int nextUniqueID(String key)
		throws Exception
	{
		return next.nextUniqueID(key);
	}
}
